package jnpf.property.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.permission.model.authorize.AuthorizeConditionModel;
import jnpf.permission.service.AuthorizeService;
import jnpf.property.entity.ZcInspectionPlanVo;
import jnpf.property.entity.ZcInspectionTaskEntity;
import jnpf.property.entity.ZcInspectionTaskItemEntity;
import jnpf.property.mapper.ZcInspectionTaskMapper;
import jnpf.property.model.inspection.ZcInspectionTaskDetail;
import jnpf.property.model.inspection.ZcInspectionTaskItemForm;
import jnpf.property.model.inspection.ZcInspectionTaskPagination;
import jnpf.property.service.ZcInspectionPlanService;
import jnpf.property.service.ZcInspectionTaskItemService;
import jnpf.property.service.ZcInspectionTaskService;
import jnpf.util.ServletUtil;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import jnpf.zcasset.entity.ZcAssetInfoEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 *
 */
@Service
public class ZcInspectionTaskServiceImpl extends ServiceImpl<ZcInspectionTaskMapper, ZcInspectionTaskEntity> implements ZcInspectionTaskService {

    @Autowired
    private UserProvider userProvider;

    @Autowired
    private AuthorizeService authorizeService;

    @Autowired
    private ZcInspectionPlanService planService;

    @Autowired
    private ZcInspectionTaskItemService taskItemService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void generateTask(String planId) {
        // 通过计划id获取计划信息
        ZcInspectionPlanVo planInfo = planService.getPlanInfo(planId);
        if (planInfo == null) {
            throw new RuntimeException("未获取到巡检计划信息");
        }
        // 判断计划是否生效.状态为发布，且在生效日期内
        DateTime effectDate = DateUtil.beginOfDay(planInfo.getEffectDate());
        DateTime lapseDate = DateUtil.endOfDay(planInfo.getLapseData());
        DateTime now = DateUtil.date();

        if (planInfo.getStatus() == 1 && DateUtil.compare(now, effectDate) >= 0 && DateUtil.compare(now, lapseDate) <= 0) {
            // 任务信息
            ZcInspectionTaskEntity taskInfo = new ZcInspectionTaskEntity();
            taskInfo.setId(IdUtil.getSnowflake(1, 1).nextIdStr());
            taskInfo.setPlanId(planId);
            taskInfo.setPlanName(planInfo.getPlanName());
            taskInfo.setProjectId(planInfo.getProjectId());
            taskInfo.setProjectName(planInfo.getProjectName());
            taskInfo.setTaskName(planInfo.getPlanName().concat(DateUtil.format(now, "yyyy-MM-dd").concat("巡检任务")));
            taskInfo.setExecutorId(planInfo.getExecutorId());
            taskInfo.setExecutorName(planInfo.getExecutorName());
            taskInfo.setTaskStatus(0);
            taskInfo.setIsAbnormal(false);
            taskInfo.setCreatorTime(now);
            // 任务时效,任务起止时间.
            taskInfo.setTaskStartTime(DateUtil.beginOfDay(now));
            taskInfo.setTaskEndTime(DateUtil.endOfDay(now));
            taskInfo.setTaskEffect(1);
            taskInfo.setEffectUnit("天");

            // 巡检项
            List<ZcAssetInfoEntity> assetList = planInfo.getAssetList();
            if (CollUtil.isNotEmpty(assetList)) {
                List<ZcInspectionTaskItemEntity> itemList = new ArrayList<>();
                assetList.forEach(asset -> {
                    ZcInspectionTaskItemEntity taskItem = new ZcInspectionTaskItemEntity();
                    taskItem.setId(IdUtil.getSnowflake(1, 1).nextIdStr());
                    taskItem.setTaskId(taskInfo.getId());
                    taskItem.setAssetId(asset.getId());
                    taskItem.setAssetName(asset.getAssetName());
                    taskItem.setStatus(0);

                    itemList.add(taskItem);
                });

                // 保存任务项
                taskItemService.saveBatch(itemList);
            }
            // 保存任务信息
            save(taskInfo);

        } else {
            throw new RuntimeException("巡检计划未生效");
        }

    }

    @Override
    public ZcInspectionTaskDetail getTaskInfo(String taskId) {
        ZcInspectionTaskDetail result = new ZcInspectionTaskDetail();

        result.setInfo(getById(taskId));
        result.setItems(taskItemService.getTaskItem(taskId));
        return result;
    }

    @Override
    public List<ZcInspectionTaskEntity> getTaskList(ZcInspectionTaskPagination pagination) {

        QueryWrapper<ZcInspectionTaskEntity> taskQueryWrapper = new QueryWrapper<>();

        boolean isPc = ServletUtil.getHeader("jnpf-origin").equals("pc");

        if (isPc) {
            // 非管理员情况
            if (!userProvider.get().getIsAdministrator()) {
                // 没Menu权限返回空集
                Object taskObj = authorizeService.getCondition(new AuthorizeConditionModel(taskQueryWrapper, pagination.getMenuId(), "zcgl_inspection_task"));
                if (ObjectUtil.isEmpty(taskObj)) {
                    return new ArrayList<>();
                } else {
                    taskQueryWrapper = (QueryWrapper<ZcInspectionTaskEntity>) taskObj;
                }
            }

        }

        // 非PC处理
        if (!isPc) {

        }

        // 条件赋值
        if (StrUtil.isNotEmpty(pagination.getTaskName())) {
            taskQueryWrapper.lambda().like(ZcInspectionTaskEntity::getTaskName, pagination.getTaskName());
        }

        if(StrUtil.isNotEmpty(pagination.getPlanId())) {
            taskQueryWrapper.lambda().eq(ZcInspectionTaskEntity::getPlanId,pagination.getPlanId());
        }

        if (CollUtil.isNotEmpty(pagination.getProjectIds())) {
            taskQueryWrapper.lambda().in(ZcInspectionTaskEntity::getProjectId, pagination.getProjectIds());
        }

        if (pagination.getTaskStatus() != null) {
            taskQueryWrapper.lambda().eq(ZcInspectionTaskEntity::getTaskStatus, pagination.getTaskStatus());
        }

        if(pagination.getIsAbnormal() != null) {
            taskQueryWrapper.lambda().eq(ZcInspectionTaskEntity::getIsAbnormal,pagination.getIsAbnormal());
        }


        //排序
        if (StringUtil.isEmpty(pagination.getSidx())) {
            taskQueryWrapper.lambda().orderByDesc(ZcInspectionTaskEntity::getId);
        } else {
            try {
                // 获取排序列
                String sortFiled = pagination.getSidx();
                ZcInspectionTaskEntity obj = new ZcInspectionTaskEntity();
                Field declaredField = obj.getClass().getDeclaredField(sortFiled);
                declaredField.setAccessible(true);
                String value = declaredField.getAnnotation(TableField.class).value();
                taskQueryWrapper = "asc".equals(pagination.getSort().toLowerCase()) ? taskQueryWrapper.orderByAsc(value) : taskQueryWrapper.orderByDesc(value);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }

        IPage<ZcInspectionTaskEntity> data = this.page(new Page<>(pagination.getCurrentPage(), pagination.getPageSize()), taskQueryWrapper);
        return pagination.setData(data.getRecords(), data.getTotal());
    }

    @Override
    public void executeTaskItem(ZcInspectionTaskItemForm form) {

        ZcInspectionTaskItemEntity item = taskItemService.getById(form.getId());

        if(item == null) {
            throw new RuntimeException("未查询到填写项");
        }

        // 设置填写信息
        item.setCheckResult(form.getCheckResult());
        item.setUploadFile(form.getUploadFile());
        item.setDescription(form.getDescription());
        item.setStatus(1);
        item.setExecTime(DateUtil.date());

        taskItemService.updateById(item);

        // 获取任务信息
        ZcInspectionTaskEntity taskInfo = getById(item.getTaskId());
        if(taskInfo != null) {
            // 判断填写内容是否不合格,如果不合格修改任务信息中是否存在异常项
            if("异常".equals(form.getCheckResult())) {
                taskInfo.setIsAbnormal(true);
            }

            // 没有任务开始时间,写入
            if(taskInfo.getExecStartTime() == null) {
                taskInfo.setExecStartTime(DateUtil.date());
                taskInfo.setTaskStatus(1);
            } else {
                LambdaQueryWrapper<ZcInspectionTaskItemEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ZcInspectionTaskItemEntity::getTaskId,taskInfo.getId()).eq(ZcInspectionTaskItemEntity::getStatus,0);
                List<ZcInspectionTaskItemEntity> toDoList = taskItemService.list(queryWrapper);
                // 没有待填写项任务完成填写,更新任务完成时间和状态
                if(CollUtil.isEmpty(toDoList)){
                    taskInfo.setExecEndTime(DateUtil.date());
                    taskInfo.setTaskStatus(2);
                }

            }
            // 更新任务信息
            updateById(taskInfo);
        }

    }

}
